/*
 *      Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *
 *  Redistributions of source code must retain the above copyright notice,
 *  this list of conditions and the following disclaimer.
 *  Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following disclaimer in the
 *  documentation and/or other materials provided with the distribution.
 *  Neither the name of the dreamlu.net developer nor the names of its
 *  contributors may be used to endorse or promote products derived from
 *  this software without specific prior written permission.
 *  Author: Chill 庄骞 (smallchill@163.com)
 */
package org.springblade.modules.course.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import org.springblade.common.enums.IntegralType;
import org.springblade.common.exception.TrainingServiceException;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.CollectionUtil;
import org.springblade.modules.classes.entity.TrainingPlanCourseEntity;
import org.springblade.modules.classes.service.ITrainingPlanCourseService;
import org.springblade.modules.classes.service.ITrainingPlanService;
import org.springblade.modules.course.entity.CourseCategoryEntity;
import org.springblade.modules.course.entity.CourseChapterEntity;
import org.springblade.modules.course.entity.CourseChapterSubEntity;
import org.springblade.modules.course.entity.CourseEntity;
import org.springblade.modules.course.mapper.CourseChapterSubMapper;
import org.springblade.modules.course.service.ICourseCategoryService;
import org.springblade.modules.course.service.ICourseChapterService;
import org.springblade.modules.course.service.ICourseChapterSubService;
import org.springblade.modules.course.vo.CourseChapterSubVO;
import org.springblade.modules.course.vo.CourseChapterVO;
import org.springblade.modules.course.vo.CourseVO;
import org.springblade.modules.course.mapper.CourseMapper;
import org.springblade.modules.course.service.ICourseService;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.modules.course.vo.TeacherCourseListVO;
import org.springblade.modules.course.wrapper.CourseWrapper;
import org.springblade.modules.log.entity.IntegralLogEntity;
import org.springblade.modules.log.service.IIntegralLogService;
import org.springblade.modules.log.vo.IntegralLogVO;
import org.springblade.modules.resource.enums.AttachType;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 课程 服务实现类
 *
 * @author junxin
 * @since 2023-03-22
 */
@Service
@AllArgsConstructor
public class CourseServiceImpl extends BaseServiceImpl<CourseMapper, CourseEntity> implements ICourseService {

	private final ICourseChapterService courseChapterService;
	private final ICourseChapterSubService courseChapterSubService;
	private final CourseChapterSubMapper courseChapterSubMapper;
	private final ICourseCategoryService courseCategoryService;
	private final IIntegralLogService integralLogService;
	private final ITrainingPlanCourseService trainingPlanCourseService;

	@Override
	public IPage<CourseVO> selectCoursePage(IPage<CourseVO> page, CourseVO course) {
		return page.setRecords(baseMapper.selectCoursePage(page, course));
	}

	@Override
	public IPage<CourseVO> selectMyselfCoursePage(IPage<CourseVO> page, CourseVO course) {
		return page.setRecords(baseMapper.selectMyselfCoursePage(page, course));
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public CourseVO getCourseInfo(Long courseId) {
		AtomicInteger flag=new AtomicInteger(0);
		Long userId=AuthUtil.getUserId();
		CourseEntity courseEntity = baseMapper.selectById(courseId);
		CourseVO resultData = CourseWrapper.build().entityVO(courseEntity);
		CourseCategoryEntity courseCategoryEntity = courseCategoryService.getById(courseEntity.getCatId());
		if (null!=courseCategoryEntity) resultData.setCategoryName(courseCategoryEntity.getCategoryName());

		//1.获取该课程的所有章节
		List<CourseChapterEntity> courseChapterList = courseChapterService.selectByCourseId(courseId);
		List<CourseChapterVO> chapterVoList = new ArrayList<>();
		if (CollectionUtils.isEmpty(courseChapterList)) {
			return resultData;
		}
		courseChapterList.forEach(chapter -> {
			CourseChapterVO vo = new CourseChapterVO();
			//2.获取该章节的所有小节
			BeanUtil.copyProperties(chapter, vo);
			List<CourseChapterSubEntity> courseChapterSubEntityList = courseChapterSubService.selectByChapterId(chapter.getId());
			List<CourseChapterSubVO> courseChapterSubVOList = new ArrayList<>();
			courseChapterSubEntityList.forEach(courseChapterSubEntity -> {
				CourseChapterSubVO courseChapterSubVO = new CourseChapterSubVO();
				BeanUtil.copyProperties(courseChapterSubEntity, courseChapterSubVO);
				if (courseChapterSubService.checkSubStudyComplete(AuthUtil.getUserId(),courseChapterSubEntity.getId()))
					courseChapterSubVO.setComplete(true);
				else flag.getAndAdd(1);//如果有小节没完成，则+1，用来判断是否所有完成了

				courseChapterSubVO.setVedioLink(courseChapterSubService.queryBySubAndCategory(courseChapterSubEntity.getId(), AttachType.COURSE_VEDIO.getCategory()).get(0).getVedioLink());
				courseChapterSubVO.setLearningCoursewareList(courseChapterSubService.queryCoursewareBySubAndCategory(courseChapterSubEntity.getId(), AttachType.COURSE_COURSEWARE.getCategory()).getLearningCoursewareList());
				courseChapterSubVOList.add(courseChapterSubVO);
			});

			vo.setChapterSubList(courseChapterSubVOList);
			chapterVoList.add(vo);

		});
		resultData.setChapterList(chapterVoList);

		if (flag.get()==0) {//表示所有小节都已完成。则判断是否已获得了该课程的积分和学时
			List<TrainingPlanCourseEntity> trainingPlanCourseEntityList = trainingPlanCourseService.selectByUserIdAndCourseId(userId, courseId);

			//如果需要考核测试 则不派发,会统一在完成课后作业之后派发
			if (CollectionUtils.isNotEmpty(trainingPlanCourseEntityList) && trainingPlanCourseEntityList.get(0).getIsExam() != 1) {
				IntegralLogEntity oldData = integralLogService.getOne(Wrappers.<IntegralLogEntity>query().lambda()
					.eq(IntegralLogEntity::getIntegralType, IntegralType.COURSE).eq(IntegralLogEntity::getIntegralResourcesId, courseId).eq(IntegralLogEntity::getUserId,userId));
				if (null==oldData){
					IntegralLogVO vo = integralLogService.generalIntegralByCourse(courseEntity);
					vo.setUserId(userId);
					integralLogService.addIntegral(vo);
				}
			}

		}
		return resultData;
	}

	@Override
	public IPage<TeacherCourseListVO> selectTeacherCourseList(IPage<TeacherCourseListVO> page, CourseVO course) {
		return page.setRecords(baseMapper.selectTeacherCourseList(page, course));
	}

	@Override
	public boolean checkCourseComplete(Long courseId,Long userId) {
		boolean flag = true;
		List<CourseChapterSubVO> courseChapterSubVOList = courseChapterSubMapper.selectCourseSub(courseId);
		if (CollectionUtil.isEmpty(courseChapterSubVOList)) return true;
		for (CourseChapterSubVO courseChapterSubVO : courseChapterSubVOList) {
			if (!courseChapterSubService.checkSubStudyComplete(userId,courseChapterSubVO.getId())) {
				flag = false;
				break;//如果有一个小节没完成 直接结束
			}
		}
		return flag;
	}

	@Transactional(rollbackFor = Exception.class)
	@Override
	public CourseChapterSubEntity createCourseAndChapterAndSub(String name) {
		//1.创建课程
		List<CourseEntity> oldCourseList = this.list(Wrappers.<CourseEntity>query().lambda().eq(CourseEntity::getName, name));
		if (CollectionUtil.isNotEmpty(oldCourseList))throw new TrainingServiceException("该课程名称已存在");
		CourseEntity courseEntity=new CourseEntity();
		courseEntity.setName(name);
		this.save(courseEntity);

		//2.创建章节
		CourseChapterEntity courseChapterEntity=new CourseChapterEntity();
		courseChapterEntity.setChapterName(name);
		courseChapterEntity.setCourseId(courseEntity.getId());
		courseChapterService.save(courseChapterEntity);

		//3.创建小节
		CourseChapterSubEntity courseChapterSubEntity=new CourseChapterSubEntity();
		courseChapterSubEntity.setSubName(name);
		courseChapterSubEntity.setCourseId(courseEntity.getId());
		courseChapterSubEntity.setChapterId(courseChapterEntity.getId());
		courseChapterSubService.save(courseChapterSubEntity);
		return courseChapterSubEntity;
	}
}
